package com.rjj.wlqq.wxpay.wxpay;

import cn.hutool.json.JSONUtil;
import com.rjj.wlqq.wxpay.wxpay.entity.*;
import com.rjj.wlqq.wxpay.wxpay.tool.EntityKit;
import com.rjj.wlqq.wxpay.wxpay.wxconfig.WXPayConfigImpl;
import com.rjj.wlqq.wxpay.wxsdk.WXPay;
import com.rjj.wlqq.wxpay.wxsdk.WXPayConfig;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * @author r
 * @date 2021/1/19 09:42
 * 微信支付
 */
@Slf4j
public abstract class WxPayKit
{

    /**
     * 基础配置信息
     */
    public abstract Wx initWx();


    /**
     * 加载配置信息
     */
    public WXPay wxPay()
    {
        try
        {
            WXPayConfig wxPayConfig = new WXPayConfigImpl(initWx());
            //默认md5加密方式
            final WXPay wxPay = new WXPay(wxPayConfig);
            wxPay.checkWXPayConfig();
            return wxPay;
        } catch (Exception e)
        {
            e.printStackTrace();
            throw new RuntimeException("加载配置失败");
        }
    }

    /**
     * 统一下单
     */
    public Map<String, String> unifiedorder(Map<String, String> map)
    {
        try
        {
            return wxPay().unifiedOrder(map);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /***
     * 支付下单方法 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
     *
     * 当tradeType参数是 NATIVE时，微信支付返回code_url来生成支付二维码，其他返回prepay_id商品id
     * @param orderNo 平台自身唯一订单号
     * @param tradeType JSAPI -JSAPI支付（返回-prepay_id） NATIVE -Native支付(返回-code_url) APP -APP支付
     * @param openId 用户在APPID中的openID
     * @param money 金额（单位：分）
     * @param profitSharing 是否为分账订单 true：是 false：否
     * @param ip 发前端ip地址
     * @param body 商品描述
     * @param notifyUrl 通知地址
     * @param attach    附件数据-附加数据，在查询API和支付通知中原样返回，可作为自定义参数使用。(我们可以传入支付类型-
     *                  处方支付    问诊支付    预约挂号等)
     *
     */
    public void unifiedorder(String orderNo, String tradeType, String openId, String money, boolean profitSharing, String ip, String attach, String notifyUrl, String body)
    {
        Map<String, String> payInfo = new HashMap<>(16);
        payInfo.put("out_trade_no", orderNo);
        payInfo.put("total_fee", String.valueOf(money));
        payInfo.put("spbill_create_ip", ip);
        payInfo.put("notify_url", notifyUrl);
        payInfo.put("trade_type", tradeType);
        payInfo.put("body", body);
        if (attach != null && !"".equals(attach))
        {
            payInfo.put("attach", attach);
        }
        //是否为分账订单，Y:是  N或不传值：否
        if (profitSharing)
        {
            payInfo.put("profit_sharing", "Y");
        }
        if ("JSAPI".equals(tradeType))
        {
            payInfo.put("openid", openId);
        } else if ("NATIVE".equals(tradeType))
        {
            payInfo.put("product_id", orderNo);
        } else
        {
            log.error("不支持其他方式");
        }
        final Map<String, String> pay = unifiedorder(payInfo);
        System.out.println(pay.toString());
    }

    /**
     * 统一下单
     * 使用方式
     * final WxOrder build = WxOrder.Builder()
     * .setOut_trade_no("p123213123133332")
     * .setTrade_type(WXPayConstants.TradeType.JSAPI.toString())
     * .setOpenid("ocd6D1hlq-Goo9DOZcXhzinAbz68")
     * .setTotal_fee("0.01")
     * .setBody("测试商品")
     * .setSpbill_create_ip("127.0.0.1")
     * .setNotify_url("http://reg.dev.tcm166.cn/pay/wx/notify")
     * .build();
     * WxPayKit wxPayKit = new WxPayKit();
     * wxPayKit.unifiedorder(build);
     */
    public Map<String, String> unifiedorder(WxOrder wxOrder)
    {
        final Map<String, String> hashMap = EntityKit.entityToHashMap(wxOrder);
        log.info("参数转化数据：{}", JSONUtil.toJsonStr(hashMap));
        final Map<String, String> unifiedorder = unifiedorder(hashMap);
        System.out.println(unifiedorder.toString());
        return unifiedorder;
    }


    /**
     * 订单查询
     * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_2
     *
     * <xml>
     * <appid>wx2421b1c4370ec43b</appid>
     * <mch_id>10000100</mch_id>
     * <nonce_str>ec2316275641faa3aacf3cc599e8730f</nonce_str>
     * <transaction_id>1008450740201411110005820873</transaction_id>
     * <sign>FDD167FAA73459FD921B144BAF4F4CA2</sign>
     * </xml>
     */
    public Map<String, String> orderQuery(Map<String, String> map)
    {
        try
        {
            wxPay().orderQuery(map);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 订单查询
     */
    public void orderQuery(PayOrderQuery payOrderQuery)
    {
        final Map<String, String> hashMap = EntityKit.entityToHashMap(payOrderQuery);
        log.info("参数转化数据：{}", JSONUtil.toJsonStr(hashMap));
        final Map<String, String> unifiedorder = orderQuery(hashMap);
        System.out.println(unifiedorder.toString());
    }

    /**
     * 关闭订单
     * https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3
     *
     * <xml>
     * <appid>wx2421b1c4370ec43b</appid>
     * <mch_id>10000100</mch_id>
     * <nonce_str>4ca93f17ddf3443ceabf72f26d64fe0e</nonce_str>
     * <out_trade_no>1415983244</out_trade_no>
     * <sign>59FF1DF214B2D279A0EA7077C54DD95D</sign>
     * </xml>
     */
    public Map<String, String> closeOrder(Map<String, String> map)
    {
        try
        {
            wxPay().closeOrder(map);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 关闭订单
     */
    public void closeOrder(String out_trade_no)
    {
        final Map<String, String> hashMap = new HashMap<>();
        hashMap.put("out_trade_no", out_trade_no);
        log.info("参数转化数据：{}", JSONUtil.toJsonStr(hashMap));
        final Map<String, String> unifiedorder = closeOrder(hashMap);
        System.out.println(unifiedorder.toString());
    }


    /**
     * 申请退款
     */
    public Map<String, String> refundOrder(Map<String, String> map)
    {
        try
        {
            wxPay().refund(map);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    public void refundOrder(OrderRefund orderRefund)
    {
        final Map<String, String> hashMap = EntityKit.entityToHashMap(orderRefund);
        log.info("参数转化数据：{}", JSONUtil.toJsonStr(hashMap));
        final Map<String, String> refundOrder = refundOrder(hashMap);
        System.out.println(refundOrder.toString());
    }

    /**
     * 退款查询
     */
    public Map<String, String> refundQuery(Map<String, String> map)
    {
        try
        {
            wxPay().refundQuery(map);
        } catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 退款查询
     */
    public void refundQuery(RefundOrderQuery refundOrderQuery)
    {
        final Map<String, String> hashMap = EntityKit.entityToHashMap(refundOrderQuery);
        log.info("参数转化数据：{}", JSONUtil.toJsonStr(hashMap));
        final Map<String, String> refundQuery = refundQuery(hashMap);
        System.out.println(refundQuery.toString());
    }

}
